package model.editormodel;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <b>In Verbindung stehende Klassen:</b> <code>LogicEditorElement</code><br>
 * <b>Funktion:</b> Dient zur Kommunikation zwischen <code>EditorModel</code>
 * und <code>EditorArea</code>. Beinhaltet einen Nachrichtentyp und die fuer die
 * View benoetigten Objekte.<br>
 * <br>
 * 
 * Wird beim Aufruf von <code>notifyObservers</code> als Objekt mitgegeben.
 * 
 * @author Team Locsi
 * 
 */
public class EditorMessage {

	/**
	 * Dieses Enum stellt den Nachrichtentyp, der angibt welche Operation im
	 * Bearbeitungsmodus angewandt wurde, zur Verfuegung.
	 * 
	 * @author Team Locsi
	 * 
	 */
	public static enum EditorMessageType {
		ADD_ELEMENT, DELETE_ELEMENTS, MOVE_ELEMENTS, CHECK_MESSAGE, REFACTORED_ELEMENT, SET_CONNECTION, DELETE_CONNECTION, LOAD_CIRCUIT, SAVE_CIRCUIT, IMPORT_COMPONENT, NEW_CIRCUIT, DELETE_CONNECTIONS, ERROR_REFACTORING, ERROR_ADDELEMENT, IS_LOGICNET, IS_LOGICCIRCUIT, IS_DEFAULT, IS_UNKNOWN, RASTER_POSITIONING
	}

	// Jede EditorMessage besitzt ein Tupel an Informationen, dabei wird
	// der Typ der Nachricht gespeichert und eine Liste die widerum
	// alle betroffenen Elemente als LogicEditorElement speichert, durch die
	// entsprechenden getter Methoden koennen diese Nachrichten dann
	// ausgewertet werden
	private EditorMessageType msgType;
	private List<LogicEditorElement> objects;
	private Input in;
	private Output out;
	private Map<Input, Output> conMap;
	private ErrorMessage erMessage;
	private String[] oNnN;

	/**
	 * Dieser Konstruktor erzeugt ein neues <code>EditorMessage</code>-Objekt.
	 * 
	 * @param msgType
	 *            <code>EditorMessageType</code> - Nachrichtentyp
	 * @param erMessage
	 *            <code>ErrorMessage</code> - zugehoerige ErrorMessage
	 */
	public EditorMessage(EditorMessageType msgType, ErrorMessage erMessage) {
		this.msgType = msgType;
		this.erMessage = erMessage;
	}

	/**
	 * Dieser Konstruktor erzeugt ein neues <code>EditorMessage</code>-Objekt.
	 * 
	 * @param msgType
	 *            <code>EditorMessageType</code> - Nachrichtentyp
	 * @param objects
	 *            <code>List</code><<code>LogicEditorElement></code> - Alle
	 *            Elemente, die fuer die aktuelle Operation benoetigt werden
	 */
	public EditorMessage(EditorMessageType msgType,
			List<LogicEditorElement> objects) {
		this.msgType = msgType;
		this.objects = objects;
	}

	/**
	 * Dieser Konstruktor erzeugt ein neues <code>EditorMessage</code>-Objekt.
	 * 
	 * @param msgType
	 *            <code>EditorMessageType</code> - Nachrichtentyp
	 * @param in
	 *            <code>Input</code> - zugehoerige Eingang einer Verbindung
	 * @param out
	 *            <code>Output</code> - zugehoeriger Output einer Verbindung
	 */
	public EditorMessage(EditorMessageType msgType, Input in, Output out) {
		this.msgType = msgType;
		this.in = in;
		this.out = out;
	}

	/**
	 * Dieser Konstruktor erzeugt ein neues <code>EditorMessage</code>-Objekt.
	 * 
	 * @param msgType
	 *            <code>EditorMessageType</code> - Nachrichtentyp
	 * @param conMap
	 *            <code>Map</code><<code>Input, Output></code> - Verbindungen
	 *            gespeichert als Paare von Inputs und Outputs, die fuer die
	 *            aktuelle Operation benoetigt werden
	 */
	public EditorMessage(EditorMessageType msgType, Map<Input, Output> conMap) {
		this.msgType = msgType;
		this.conMap = conMap;
	}

	/**
	 * Dieser Konstruktor erzeugt ein neues <code>EditorMessage</code>-Objekt.
	 * 
	 * @param msgType
	 *            <code>EditorMessageType</code> - Nachrichtentyp
	 */
	public EditorMessage(EditorMessageType msgType) {
		this.msgType = msgType;
	}

	/**
	 * Dieser Konstruktor erzeugt ein neues <code>EditorMessage</code>-Objekt.
	 * 
	 * @param msgType
	 *            <code>EditorMessageType</code> - Nachrichtentyp
	 * @param oNnN
	 *            <code>String[]</code>- oldName und newName in dieser Reihenfolge
	 */
	public EditorMessage(EditorMessageType msgType, String[] oNnN) {
		this.msgType = msgType;
		this.oNnN = oNnN;
	}

	/**
	 * Gibt die Objekte, die fuer die aktuelle Operation benoetigt werden,
	 * zurueck.
	 * 
	 * @return <code>List</code><<code>LogicEditorElement></code> - die Objekte,
	 *         die fuer die aktuelle Operation benoetigt werden,
	 *         <code>null</code> falls kein Element fuer die Operation gefunden
	 *         werden konnte bzw. etwas nicht korrekt ab- gelaufen ist
	 */
	public List<LogicEditorElement> getObjects() {
		return Collections.unmodifiableList(objects);
	}

	/**
	 * Diese Methode ermoeglicht es auf den Input, also der Senke einer
	 * Verbindung die erzeugt wurde zu zugreifen
	 * 
	 * @return <code>Input</code> - Senke einer Verbindung
	 */
	public Input getInputOfConnection() {
		return this.in;
	}

	/**
	 * Diese Methode ermoeglicht es auf den Output, also der Quelle einer
	 * Verbindung die erzeugt wurde zu zugreifen
	 * 
	 * @return <code>Output</code> - Quelle einer Verbindung
	 */
	public Output getOutputOfConnection() {
		return this.out;
	}

	/**
	 * Diese Methode ermoeglicht es mehrere Verbindungen mit einem Aufruf zu
	 * loeschen
	 * 
	 * @return <code>Map</code><<code>Input, Output></code> - die zu loeschenden
	 *         Verbindungen
	 */
	public Map<Input, Output> getConnectionMap() {
		return this.conMap;
	}

	/**
	 * Gibt den Nachrichtentyp zurueck.
	 * 
	 * @return <code>EditorMessageType</code> - den Nachrichtentyp
	 */
	public EditorMessageType getMsgType() {
		return msgType;
	}

	/**
	 * Diese Methode gibt die ErrorMessage zurueck.
	 * 
	 * @return <code>ErrorMessage</code> - Art des Fehlers
	 */
	public ErrorMessage getErMessage() {
		return this.erMessage;
	}

	/**
	 * Gibt das String-Array mit dem alten und neuen Namen zurueck.
	 * 
	 * @return <code>String[]</code> - alte und neue Namen
	 */
	public String[] getoldNameNewName() {
		return oNnN;
	}
}